package whf.framework.entity.ext;

import java.util.List;

import whf.framework.entity.TreeNode;
import whf.framework.log.Log;
import whf.framework.log.LogFactory;
import whf.framework.meta.MetaFactory;
import whf.framework.security.UserContext;
import whf.framework.service.TreeService;
import whf.framework.util.BeanFactory;
import whf.framework.util.PermissionUtils;
import whf.framework.util.StringUtils;
import whf.framework.util.ThreadContext;
import whf.framework.util.Utils;

/**
 * 可以自动搜索子节点的树对象
 * @author wanghaifeng
 * @create Jan 21, 2007 5:58:13 PM
 * 
 */
public class TreeItem implements TreeNode<TreeItem>{
	private static Log log = LogFactory.getLog(TreeItem.class);
	
	private long id;
	
	private String name;
	
	private TreeItem parent;
	
	private List<TreeItem> children;
	
	private TreeService service;
	
	private String queryString;
	
	private int deepth;
	
	private int maxDeepth;
	
	private TreeNode treeItem;
	
	private String icon;
	
	private UserContext userContext = ThreadContext.getUserContext();
	
	private TreeItem(TreeNode item, TreeService service, String queryString, int deepth, int maxDeepth){
		if(item != null){
			this.id = item.getId();
			this.name = item.getName();
		}
		this.treeItem = item;
		this.service = service;
		this.queryString = queryString;
		this.deepth = deepth;
		if(maxDeepth == -1){
			this.maxDeepth = Integer.MAX_VALUE;
		} else {
			this.maxDeepth = maxDeepth;
		}
	}
	
	public TreeItem(TreeNode root, TreeService service, String queryString, int maxDeepth){
		this(root, service, queryString, 0, maxDeepth);
		this.initChildren();
	}
	
	public TreeItem(String boClassName) throws Exception{
		this((TreeNode)null, (TreeService)BeanFactory.getService(MetaFactory.findByModelClass(Utils.getClassByClassName(boClassName))), (String)null, -1);
	}
	
	private void initChildren(){
		try{
			List<TreeNode> list = this.service.findChildren(this.treeItem, this.queryString);
			this.children = Utils.newArrayList();
			for(TreeNode item: list){
				boolean canAdd = PermissionUtils.hasPermission(this.userContext, item);
				if(canAdd){
					TreeItem child = new TreeItem(item, this.service, this.queryString, this.deepth + 1, this.maxDeepth);
					child.parent = this;
					this.children.add(child);
					if(this.deepth < this.maxDeepth){	//增加子节点
						child.initChildren();
					}
				}
			}
		} catch(Exception e){
			log.error(this, e);
		}
	}
	
	public long getId(){
		return this.id;
	}
	
	public String getName(){
		return this.name;
	}
	
	public TreeItem getParent(){
		return this.parent;
	}
	
	/**
	 * @param parent the parent to set
	 */
	public void setParent(TreeItem parent) {
		this.parent = parent;
	}

	/* (non-Javadoc)
	 * @see whf.framework.entity.ITreeItem#isLeaf()
	 */
	public boolean isLeaf() {
		return this.children.isEmpty();
	}

	public List<TreeItem> getChildren(){
		return this.children;
	}
	
	public boolean isRoot(){
		return this.id == 0;
	}
	
	public int getDeepth(){
		return this.deepth;
	}
	
	public String getIcon(){
		if(this.icon == null){
			return "";
		} else {
			return this.icon;
		}
	}
	
	public TreeNode getTreeItem(){
		return this.treeItem;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Comparable#compareTo(T)
	 */
	public int compareTo(Object o) {
		TreeItem item = (TreeItem)o;
		return StringUtils.compare(this.name, item.name);
	}
	
	public String toString(){
		StringBuilder sb = new StringBuilder();
		for(int i=0; i< this.deepth; i++){
			sb.append("\t");
		}
		sb.append("{L:").append(this.deepth).append("}");
		sb.append(id).append("\t").append(name).append("\t").append("\t@").append(this.parent!= null?this.parent.getId():-1).append("\n");
		for(int i=0; i< this.deepth; i++){
			sb.append("\t");
		}
		sb.append(this.children);
		return sb.toString();
	}
	
	public static void main(String[] args) throws Exception{
		System.out.println(new TreeItem("whf.framework.web.menu.entity.MenuItem"));
	}
}
